清羽AI正在绞尽脑汁想思路ING···
清羽のAI摘要
GLM-4-Flash

碎碎念

今天是六一儿童节,祝大家儿童节快乐呀!

芜湖!论文终于写完咯!查重率2%,AIGC率10%,鸡登AIGC查重,等我搞完这些事,我高低水一篇文章:《浅谈AIGC论文检测》!太抽象了!

由于入手了1Panel专业版,总得物尽其用,所以后面也会围绕这个展开网站服务啦,原来的博客更新的步骤如下:github更新,action部署,部署到gitea国内镜像,触发Webhook,服务器拉取,触发CDNAPI刷新缓存,最终实现了更新。

但是使用1Panel后,由于官方暂未支持webhook,所以无法通知到服务器,并执行命令,所以只能手动执行git pull,很抽象啊,这我怎么受得了,所以上网查了很多资料,通过action链接ssh执行命令,最终实现了完全自动的步骤,下面分享一下教程。

顺便,写了个自动识别是否需要hexo algolia的教程,有需要的话自行取用啦!废话不多说,开始教程!

教程

自动更新

前置要求

在执行该系列操作之前,默认你已经实现了github构建并生成静态文件,部署到静态分支或者静态仓库的操作,所以本教程不对这部分操作进行详细说明,如果你没有完成,可以参考以下action工作流尝试配置,注意打开仓库设置中,action的读写权限:

https://gist.liushen.fun/LiuShen/github-action-hexo-deploy

以下教程也会基于该action进行进一步添加。

实现该步骤我们分为以下几个小点,首先是镜像仓库,再就是配置服务器的SSH链接,并在服务器执行命令。

镜像仓库

由于需要部署到服务器的基本上都是国内服务器,国内服务器链接github略微有些困难,虽然说可以使用ghproxy之类的加速服务,但是仍然不如将仓库放在国内镜像中好用。

所以我们选择一个国内国外均可访问的git仓库服务,比如giteegitlabcodingcnb,这里我选择了腾讯的最新服务:CNB,当然你完全可以选择其他任何国际Git平台,可以自行在服务器克隆一个开源仓库进行测速。最近的gitee似乎有点抽筋,经过实测,在github action中推送速度极慢,平均七八分钟才可以git push成功,较为影响使用,所以个人不太建议。

注意,建议构建好的静态产物仓库为开源仓库(因为闭源了也可以直接扒站获取),方便服务器拉取,否则可能需要自行配置ssh密钥进行免密拉取。

创建仓库Token

如果你选择就使用github作为静态资源仓库,那么无需申请tokenaction内置的参数即可实现,如果你选择cnb你可以在以下地址中申请token

你应该会得到一个用户名(cnb)和一个token,保存下来,然后创建一个初始仓库,比如命名为Blog,任意添加一个文件到main分支,防止后面推送的时候出现找不到分支的情况。

如果你选择gitee,可以尝试进入私人令牌页面申请,其他平台我就不赘述了,这一步网络上应该会有极为完善的教程。

添加密钥

如果你选择了cnb平台,需要在你的hexogithub 密钥内添加两个变量:CNB_USERNAMECNB_TOKEN

添加变量

添加工作流

然后在action文件中,最后一步的部署,添加以下命令:

1
2
3
4
5
6
7
8
9
10
11
12
- name: 部署
run: |
cd ./public
git init
git config --global user.name 'GitHub Action'
git config --global user.email 'action@github.com'
git add .
git commit -m "${{ github.event.head_commit.message }}==>[$(date +"%Y-%m-%d %H:%M:%S")]"
git push --force --quiet "https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" master:page
git branch -M main
git remote add origin "https://${{ secrets.CNB_USERNAME }}:${{ secrets.CNB_TOKEN }}@cnb.cool/Liiiu/Blog.git"
git push --force --quiet origin main

这里,我首先推送到了github同仓库的page分支,方便查看,后面才推送到了cnb的仓库中,这里的地址,请根据你个人实际情况进行修改。

如果你选择的是github,或者gitee等平台,也完全可以仿照上面进行配置,配置完全一致。

下面尝试触发action更新,如果一切正常,构建完成后,你应该会在cnb上看到博客构建出来的静态源码,比如我的

SSH执行拉取

下面实现通过action,链接服务器SSH,并在服务器中执行拉取的命令。

获取密钥密码

实现1Panel本地静态文件自动更新,建议使用密钥登录,安全性更高,首先在1Panel中的密钥信息,生成密码和密钥,以便于后面登录:

生成密钥

添加变量

此次添加变量较多,有:SERVER_IPUSERNAMEPASSPHRASEKEYPORT五个变量,如下:

  • SERVER_IP:服务器IP
  • USERNAMESSH链接用户名,一般为root
  • PASSPHRASE:密钥密码,用来提升强度用
  • KEY:密钥
  • PORTSSH登录端口,一般为22
克隆仓库

此时,需要在服务器手动克隆一次仓库,这样才能获得git配置,后面才可以通过直接在目录下git pull实现增量拉取,相比于克隆一个新的仓库,速度更快。

先创建静态仓库网站,比如blog.liushen.fun,最终的静态目录如下:

静态目录地址

在任意目录下克隆一次Blog静态资源仓库,因为1Panel V1版本不支持自定义部署目录,所以需要将克隆下来的文件夹内的所有文件,包括.git文件夹,复制到index文件夹内,这样才能确保后续可以直接在index文件夹内,执行拉取命令,实现文件更新。

如果在前面你选择的是github存储构建产物静态文件,你可以用ghproxy之类的镜像拉取,后面git pull也会走这个链接,但是不太建议,因为一般这种镜像都不太稳定,可能需要频繁更换。

添加工作流

下面就可以修改action实现推送时自动拉取了,在部署的下方添加另一个工作流:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- name: 服务器执行拉取命令
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
passphrase: ${{ secrets.PASSPHRASE }}
port: ${{ secrets.PORT }}
script: |
cd /opt/1panel/apps/openresty/openresty/www/sites/blog.liushen.fun/index/
git config --global --add safe.directory "$(pwd)"
git fetch --all --depth=1
git reset --hard origin/main
git pull --depth=1
echo "✅ 已拉取 page 分支最新内容"

再次尝试修改并触发,如果一切正常,仓库文件自动触发推送到服务器应该就实现了!

当前结果完成后,完整的action配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
name: 自动部署

on:
push:
branches:
- main

release:
types:
- published

workflow_dispatch:

env:
TZ: Asia/Shanghai

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 检查分支
uses: actions/checkout@main
with:
ref: main

- name: 缓存项目 npm
id: cache-node-modules
uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-${{ matrix.node-version }}-nodeModules-${{ hashFiles('package-lock.json') }}-${{ hashFiles('package.json') }}
restore-keys: |
${{ runner.os }}-nodeModules-

- name: 安装 Node
uses: actions/setup-node@main
with:
node-version: "20.x"

- name: 安装 Hexo 压缩插件
run: |
npm install hexo-cli --global
npm install gulp-cli --global

- name: 安装依赖
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: |
npm install

- name: 清理文件树
run: |
npm run clean

- name: 生成友链数据 # 这一步是我自己的配置,看你自己的需要,用于友链朋友圈
run: |
node ./link.js

- name: 生成静态文件
run: |
npm run build

- name: 执行 SWPP Gulp
run: |
hexo swpp
gulp

- name: 部署
run: |
cd ./public
git init
git config --global user.name 'GitHub Action'
git config --global user.email 'action@github.com'
git add .
git commit -m "${{ github.event.head_commit.message }}==>[$(date +"%Y-%m-%d %H:%M:%S")]"
git push --force --quiet "https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" master:page
git branch -M main
git remote add origin "https://${{ secrets.CNB_USERNAME }}:${{ secrets.CNB_TOKEN }}@cnb.cool/Liiiu/Blog.git"
git push --force --quiet origin main

- name: 服务器执行拉取命令
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
passphrase: ${{ secrets.PASSPHRASE }}
port: ${{ secrets.PORT }}
script: |
cd /opt/1panel/apps/openresty/openresty/www/sites/blog.liushen.fun/index/
git config --global --add safe.directory "$(pwd)"
git fetch --all --depth=1
git reset --hard origin/main
git pull --depth=1
echo "✅ 已拉取 page 分支最新内容"

在最下面,这里我采用了强制拉取,并且只保留了深度为一的拉取记录,这样可以防止由于文件冲突导致可能拉取不下来的问题,并且控制了拉去的日志文件大小。

自动执行algolia

功能说明

由于algolia的更新是需要独立执行命令的,并且执行的时候会重新构建,如果每次action构建都需要执行一次,会增加没必要的构建时间,拖慢更新速度,所以写了这样的功能,程序可以自己判断是否有新文章,如果有,则自动执行hexo algolia命令,如果没有,则跳过。

打开权限

首先,在仓库的设置中,打开action对仓库的读写权限,这样才能访问到上次action所生成的文件列表:

开启权限

添加脚本

然后,再在仓库中添加文件.github/scripts/compare_posts.sh文件,后续会通过该文件执行对比命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash

PREV_DIR=".github/prev-posts"
CURR_DIR=".github/current-posts"

# 保存当前 posts 文件结构信息
mkdir -p "$CURR_DIR"
find ./source/_posts -type f | sort > "$CURR_DIR/filelist.txt"

# 判断是否存在上次构建文件记录
if [ -f "$PREV_DIR/filelist.txt" ]; then
if cmp -s "$PREV_DIR/filelist.txt" "$CURR_DIR/filelist.txt"; then
echo "no_update" > .github/posts_update_status.txt
else
echo "updated" > .github/posts_update_status.txt
fi
else
echo "first_run" > .github/posts_update_status.txt
fi

添加工作流

action的工作流文件中,添加以下命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
- name: 下载上一次构建的 posts 文件清单
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: main
name: 'prev-posts'
path: '.github/prev-posts'
if_no_artifact_found: warn
continue-on-error: true

- name: 保存当前 posts 文件清单并比较差异
run: |
bash .github/scripts/compare_posts.sh

- name: 决定是否执行 Algolia
id: decide-algolia
run: |
status=$(cat .github/posts_update_status.txt)
echo "Posts Update Status: $status"
if [ "$status" = "updated" ] || [ "$status" = "first_run" ]; then
echo "should_run_algolia=true" >> $GITHUB_ENV
else
echo "should_run_algolia=false" >> $GITHUB_ENV
fi

- name: 保存当前 posts 文件清单为 artifact
uses: actions/upload-artifact@v4
with:
name: prev-posts
path: .github/current-posts/filelist.txt
retention-days: 60

- name: 生成静态文件 # 这部分已经存在,用于定位
run: |
npm run build

- name: 执行 Algolia 更新
if: ${{ env.should_run_algolia == 'true' }}
run: |
echo "执行 Algolia 更新"
hexo algolia

具体添加位置为:下载上一次构建的 posts 文件清单决定是否执行 Algolia放在生成静态文件之前,执行Algolia更新放在构建之后,前半部分会分析是否需要执行命令,并添加一个环境变量告诉后面是否需要执行,后半部分则根据环境变量进行选择性执行命令。

这个脚本的原理是,每次执行命令会获取到上一次构建所得到的产物,放在目录下,通过刚才的对比脚本进行新文件结构和原始文件结构对比,最终实现判断是否需要更新。

完整工作流

到了这一步,完整的工作流文件示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
name: 自动部署

on:
push:
branches:
- main

release:
types:
- published

workflow_dispatch:

env:
TZ: Asia/Shanghai

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 检查分支
uses: actions/checkout@main
with:
ref: main

- name: 缓存项目 npm
id: cache-node-modules
uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-${{ matrix.node-version }}-nodeModules-${{ hashFiles('package-lock.json') }}-${{ hashFiles('package.json') }}
restore-keys: |
${{ runner.os }}-nodeModules-

- name: 安装 Node
uses: actions/setup-node@main
with:
node-version: "20.x"

- name: 安装 Hexo 压缩插件
run: |
npm install hexo-cli --global
npm install gulp-cli --global

- name: 安装依赖
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: |
npm install

- name: 清理文件树
run: |
npm run clean

- name: 生成友链数据
run: |
node ./link.js

- name: 下载上一次构建的 posts 文件清单
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: main
name: 'prev-posts'
path: '.github/prev-posts'
if_no_artifact_found: warn
continue-on-error: true

- name: 保存当前 posts 文件清单并比较差异
run: |
bash .github/scripts/compare_posts.sh

- name: 决定是否执行 Algolia
id: decide-algolia
run: |
status=$(cat .github/posts_update_status.txt)
echo "Posts Update Status: $status"
if [ "$status" = "updated" ] || [ "$status" = "first_run" ]; then
echo "should_run_algolia=true" >> $GITHUB_ENV
else
echo "should_run_algolia=false" >> $GITHUB_ENV
fi

- name: 保存当前 posts 文件清单为 artifact
uses: actions/upload-artifact@v4
with:
name: prev-posts
path: .github/current-posts/filelist.txt
retention-days: 60

- name: 生成静态文件
run: |
npm run build

- name: 执行 Algolia 更新
if: ${{ env.should_run_algolia == 'true' }}
run: |
echo "执行 Algolia 更新"
hexo algolia

- name: 执行 SWPP Gulp
run: |
hexo swpp
gulp

- name: 部署
run: |
cd ./public
git init
git config --global user.name 'GitHub Action'
git config --global user.email 'action@github.com'
git add .
git commit -m "${{ github.event.head_commit.message }}==>[$(date +"%Y-%m-%d %H:%M:%S")]"
git push --force --quiet "https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" master:page
git branch -M main
git remote add origin "https://${{ secrets.CNB_USERNAME }}:${{ secrets.CNB_TOKEN }}@cnb.cool/Liiiu/Blog.git"
git push --force --quiet origin main

- name: 服务器执行拉取命令
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
passphrase: ${{ secrets.PASSPHRASE }}
port: ${{ secrets.PORT }}
script: |
cd /opt/1panel/apps/openresty/openresty/www/sites/blog.liushen.fun/index/
git config --global --add safe.directory "$(pwd)"
git fetch --all --depth=1
git reset --hard origin/main
git pull --depth=1
echo "✅ 已拉取 page 分支最新内容"

这样,就可以实现整个流程啦!

总结

1Panel确实很好用,v2版本还有多机管理,狠狠期待住了,目前入手了一个新香港机器,后面可以用来作为从机进行使用,并且更加方便链接国外网络环境。

webhook很好用,但是1Panel确实不是很支持,希望后续可以支持上,毕竟webhook的安全性还是更强一些,ssh链接的方式还是稍微有点依赖于github平台了,不过不管怎么说,目前也是实现啦!

每日一图

图片来自哲风壁纸

帅逼大狗子